//
// file : win_test.cpp
// date : 09/17/07
//
// 
#include <stdio.h>
#include <string.h>

#include "inet_ipc.h"
#include "inet_apc.h"


/* tcp ping */

#include <signal.h>

static g_quit = 0;

void sig_int(int sig)
{
    if( sig == SIGINT ) g_quit = 1;
}

long __stdcall tpong(void *ctx, long len)
{
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    ipc->ibound[1]= 'o'; //Ping->Pong

    ipc->ipoint += len;

    ipc->ibound[len] = '\0';

    //len = send( ipc->socket, ipc->ibound, ipc->ipoint, 0); 
    len = ipc_writing(ipc->sessid, ipc->ibound, ipc->ipoint);

    ipc_print("[%d]%s", len, ipc->ibound);

    return 0;
}

// tcp server
long tcp_pong(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = tcp_service(didx, addr_str, 0);

    if( sid < 0 )
    {
        printf(" udp_pong: udp_session=%d\n", sid);
        return sid; // error
    }

    // set reader
    e = set_freader(sid, tpong);


    if( e < 0 )
    {
        printf(" tcp_echo: tcp_echo(%s)=%d\n", addr_str, e);
        return e;
    }

    return sid;
}

//
// a timer routine
//
long __stdcall tping(void *ctx)
{
    SYSTEMTIME st;
    ipccb_t   *ipc = (ipccb_t*)ctx;
    int        len;

    GetSystemTime(&st);

    ipc->ocount = sprintf(ipc->obound,
                          "Ping to(%s:%d) %.2d%.2d%.2d:%.2d%.2d%.2d.%.3d\n",
                          inet_ntoa(ipc->toaddr.sin_addr),
                          ntohs(ipc->toaddr.sin_port),
                          st.wMonth, st.wDay, st.wYear, st.wHour,
                          st.wMinute, st.wSecond, st.wMilliseconds);

    //len = send(ipc->socket, ipc->obound, ipc->ocount, 0);
    len = ipc_sending( ipc );

    ipc_print("[%d]%s", len, ipc->obound);

    if( len >= 0 )
    {
       ipc->ocount -= len;  // must clear ocount or it be sent twice
    }
    else
    {
        ipc_print(" tping failed\n");
    }

    return len;
}

long __stdcall techo(void *ctx, long len)
{
    static int cc=0;
    ipccb_t  *ipc = (ipccb_t*)ctx;

    // incoming data in ibound
    len += ipc->ipoint;

    ipc->ibound[len] = '\0';

    ipc_print("echo %s", ipc->ibound);

    ipc_closing( ipc );

    return 0;
}

extern long tcp_ping(char *addr_str, long didx);

void __stdcall my_timer(struct utimer_t *tb)
{
    ipc_print(" [%d] my_timer ticks=%d delay=%d\n", GetTickCount(), tb->ut_ticks, tb->ut_delay);

    long  didx = (long)tb->ut_param[0];
    char *addr = (char*)tb->ut_param[1];

    tcp_ping(addr, didx);

}
long __stdcall tredo( void *ctx )
{
    utimer_t  ut;
    ipccb_t  *ipc = (ipccb_t*)ctx;

    ipc_print(" restart...\n");

    memset(&ut, 0, sizeof(ut));

    ut.ut_delay = 1000;
    ut.ut_awake = my_timer;
    ut.ut_param[0] = ipc->usrobj[0];
    ut.ut_param[1] = ipc->usrobj[1];

    ipc_loadtmr(ipc->sessid, &ut);

    return 0;
}

long tcp_ping(char *addr_str, long didx)
{
    long sid;
    long e;

    sid  = tcp_session(didx);  // ipc block for udp

    if( sid < 0 )
    {
        printf(" tcp_ping: tcp_session=%d\n", sid);
        return sid; // error
    }
    // set reader
    e = set_freader(sid, techo);
    e = set_fclosed(sid, tredo);
    e = set_fwriter(sid, tping);

    set_userobj(sid, 0, (void*)didx);
    set_userobj(sid, 1, addr_str);

    e = tcp_connect(sid, addr_str);

    if( e < 0 )
    {
        void * ctx;

        ctx = ipc_reclaim( sid );

        tredo( ctx );

        printf(" tcp_ping: tcp_connect(%s)=%d\n", addr_str, e);

        return e;
    }

    return sid;
}

int main(int argc, char *argv[])
{
    unsigned short port;
    unsigned long  addr;
    long didx=0;
    long sid;

    port = 0;
    addr = 0;

    if( argc < 3 )
    {
print_help:
        printf("Uasge:\t%s {ping|pong} [ip addr:]port\n", argv[0]);
        return 0;
    }

    signal(SIGINT, sig_int);

    if( stricmp( argv[1], "ping") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = tcp_ping( argv[2], didx );

        while( sid > 0 && g_quit == 0 ) Sleep(1000);

        sid = 0;
    }
    else if( stricmp( argv[1], "pong") == 0 )
    {
        didx = ipc_startup(5, 0);

        sid = tcp_pong( argv[2], didx );

        while( sid > 0 && g_quit == 0 ) Sleep(1000);
    }
    else goto print_help;

    if( didx )
    {
        if( sid > 0 ) ipc_shutoff( sid );
    }

    ipc_cleanup( didx);

    printf(" exit..\n");

    return 0;
}
